home *** CD-ROM | disk | FTP | other *** search
- /*
- * Uudecode -- decode a uuencoded file back to binary form.
- *
- * modified for Lattice C on the ST - 11.05.86 by MSD
- * modified for Alcyon on the ST - 10-24-86 by RDR
- * modified (a lot) for MWC on the ST 02/07/87 by JPHD
- * (Some more to be done on the I/O speed...)
- *
- */
-
- #include <stdio.h>
- #include <osbind.h>
-
- extern FILE *fopen();
- extern char *strcpy();
-
- char *getnword();
-
- #define MAXCHAR 127
- #define LINELEN 80
- #define FILELEN 64
- #define CODEDLN 61
- #define NORMLEN 45
-
- char *mism = "Part suffix mismatch: <%> instead of <%>.\r\n";
- #define SUBS1 23
- #define SUBS2 38
-
- FILE *in, *out;
- char ifname[FILELEN];
- char chtbl[MAXCHAR];
- char *pos;
- char blank, part = '\0';
- int partn = 'a';
- int lens;
-
- main(argc, argv) int argc; char *argv[];
- {
- register int i, j;
- char dest[FILELEN], buf[LINELEN];
-
- if (argc < 2) {
- Console("Almost foolproof uudecode v1.0 15-Feb-1987 JPHD\r\n");
- Console("Usage: uudecode inputfile\r\n");
- exit(1);
- }
- if((in = fopen(argv[1], "r")) == NULL) {
- Console("Cant open input file.\r\n");
- exit(2);
- }
-
- /*
- * Set up the default translation table.
- */
- for (i = 0; i < ' '; i++) chtbl[i] = '\0';
- for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j;
- for (i = ' ' + 64; i < MAXCHAR; i++) chtbl[i] = '\0';
- chtbl['`'] = chtbl[' ']; /* common mutation */
- chtbl['~'] = chtbl['^']; /* an other common mutation */
- blank = ' ';
- /*
- * search for header or translation table line.
- */
- for (;;) {
- if (fgets(buf, sizeof buf, in) == NULL) {
- Console("No begin line\r\n");
- exit(3);
- }
- if (strncmp(buf, "table", 5) == 0) {
- gettable();
- continue;
- }
- if (strncmp(buf, "begin", 5) == 0) {
- break;
- }
- }
- lens = strlen(buf);
- if (lens) buf[--lens] = '\0';
- if ((pos = getnword(buf, 3)) == NULL) {
- Console("Missing filename in begin line.\r\n");
- exit(10);
- } else
- strcpy(dest, pos);
-
- if((out = fopen(dest, "wb")) == NULL) {
- Console("Cannot open output file\r\n");
- exit(4);
- }
- decode();
- fclose(out);
- exit(0);
- }
- /*
- * Bring back a pointer to the start of the nth word.
- */
- char *getnword(str, n) register char *str; register int n;
- {
- while((*str == '\t') || (*str == ' ')) str++;
- if (! *str) return NULL;
- while(--n) {
- while ((*str != '\t') && (*str != ' ') && (*str)) str++;
- if (! *str) return NULL;
- while((*str == '\t') || (*str == ' ')) str++;
- if (! *str) return NULL;
- }
- return str;
- }
-
- /*
- * Install the table in memory for later use.
- */
- gettable()
- {
- char buf[LINELEN];
- register int c, n = 0;
- register char *cpt;
-
- for (c = 0; c <= MAXCHAR; c++) chtbl[c] = '\0';
-
- again: if (fgets(buf, sizeof buf, in) == NULL) {
- Console("EOF while in translation table.\r\n");
- exit(5);
- }
- if (strncmp(buf, "begin", 5) == 0) {
- Console("Incomplete translation table.\r\n");
- exit(6);
- }
- cpt = buf + strlen(buf) - 1;
- *cpt = ' ';
- while (*(cpt) == ' ') {
- *cpt = '\0';
- cpt--;
- }
- cpt = buf;
- while (c = *cpt) {
- if (chtbl[c] != '\0') {
- Console("Duplicate char in translation table.\n");
- exit(6);
- }
- if (n == 0) blank = c;
- chtbl[c] = n++;
- if (n >= 64) return;
- cpt++;
- }
- goto again;
- }
-
- /*
- * copy from in to out, decoding as you go along.
- */
-
- decode()
- {
- char buf[LINELEN], outl[LINELEN];
- register char *bp, *ut, *trtbl = chtbl;
- register unsigned int n, c, len;
-
- for (;;) {
- if (fgets(buf, sizeof buf, in) == NULL) {
- Console("Short file.\r\n");
- return;
- }
- len = strlen(buf);
- if (len) buf[--len] = '\0';
- /*
- * Get the binary line length.
- */
- n = trtbl[*buf];
- if (n == NORMLEN) goto decod;
- /*
- * end of uuencoded file ?
- */
- if (strncmp(buf, "end", 3) == 0) return;
- /*
- * end of current file ? : get next one.
- */
- if (strncmp(buf, "include", 7) == 0) {
- getfile(buf);
- continue;
- }
- /*
- * Is it the empty line before the end line ?
- */
- if (n <= 0) continue;
- /*
- * Pad with blanks.
- */
- decod: for (bp = &buf[c = len];
- c < CODEDLN; c++, bp++) *bp = blank;
-
- /*
- * output a group of 3 bytes (4 input characters).
- * the input chars are pointed to by p, they are to
- * be output to file f. n is used to tell us not to
- * output all of them at the end of the file.
- */
- ut = outl;
- len = n;
- bp = &buf[1];
- while (n > 0) {
- *(ut++) = trtbl[*bp] << 2 | trtbl[bp[1]] >> 4;
- n--;
- if (n) {
- *(ut++) = trtbl[bp[1]] << 4 | trtbl[bp[2]] >> 2;
- n--;
- }
- if (n) {
- *(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]];
- n--;
- }
- bp += 4;
- }
- n = fwrite(outl, 1, len, out);
- }
- }
-
- /* you may need to rename the filenames at the ends of each part
- * if the encoder encoded them on directories and specified drives.
- */
- getfile(buf) register char *buf;
- {
- if ((pos = getnword(buf, 2)) == NULL) {
- Console("Missing include file name.\r\n");
- exit(11);
- } else
- strcpy(ifname, pos);
-
- if (freopen(ifname, "r", in) != in) {
- Console("Cannot reassign input file to included file.\r\n");
- exit(7);
- }
- for (;;) {
- if (fgets(buf, LINELEN, in) == NULL) {
- Console("No begin line in included file: ");
- Console(ifname);
- Console(".\r\n");
- exit(3);
- }
-
- if (strncmp(buf, "table", 5) == 0) {
- gettable();
- continue;
- }
- if (strncmp(buf, "begin", 5) == 0) {
- break;
- }
- }
- lens = strlen(buf);
- if (lens) buf[--lens] = '\0';
- if ((pos = getnword(buf, 3)) == NULL ) {
- Console("Missing part name, in included begin line.\r\n");
- part = '?';
- } else {
- part = *pos;
- /*
- * Check the part suffix.
- */
- partn++;
- if (part != partn) {
- mism[SUBS1] = part;
- mism[SUBS2] = partn;
- Console(mism);
- }
- }
- }
-
- /*
- * Output to console, immune against redirection of stdout.
- */
- Console(s) register char *s;
- {
- while (*s) Bconout(2,*s++);
- }
-